home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
msysjour
/
vol07
/
04
/
netbios2
/
netio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-01
|
35KB
|
1,149 lines
/****************************************************************************
PROGRAM: NETIO.C
PURPOSE: Contains function calls which call NetBIOS commands
as well as Remote Browser "Client" calls. The
Remote Browser "Server" code resides in Server.c
NOTE: 1. ALL NETBIOS FUNCTIONS ASSUME SINGLE LAN ADAPTOR
HENCE, ncb_lana IS ALWAYS SET TO 0.
2. Client can only connect to one remote Server
at a time.
FUNCTIONS:
AddName - Adds a unique name to local name table.
(uses NCB.ADD.NAME )
DeleteName - Deletes a unique name to local name table.
(uses NCB.DELETE.NAME )
Listen - Posts a listen. Does not wait for completion
(uses NCB.LISTEN | ASYNCH )
Call - Posts a call. Waits for completion, but yields
control for other apps to run
(uses NCB.CALL | ASYNCH )
Send - Posts a send. Waits for completion, but yields
control for other apps to run
(uses NCB.SEND | ASYNCH )
Receive - Posts a receive any. For client
applications, waits for completion,
but yields control for other apps to run.
For server application, does not wait
for completion
(uses NCB.RECEIVE.ANY | ASYNCH )
Hangup - Hangs up a local session. Synchronous
(uses NCB.HANGUP)
Cancel - Cancels a sumitted NCB. Synchronous
(uses NCB.CANCEL)
R_getcwd - It performs a remote "get current
working directory". Caller is assumed to
be a client. A session must have been
set up already with remote server.
R_dos_findfirst - It performs a remote "dos find first"
Caller is assumed to be a client. A session must have been
set up already with remote server.
R_dos_findnext - It performs a remote "dos find next"
Caller is assumed to be a client. A session must have been
set up already with remote server. Furthermore,
a R_dos_findfirst must have been called
prior to calling this routine.
History:
January, 1992 Alok Sinha Created
****************************************************************************/
// Include Files
#include <windows.h>
#include "ncb.h"
#include "state.h"
#include "common.h"
#include "netio.h"
#include "wnetbios.h"
#include <time.h>
#include <string.h>
// Global data
extern CallStatus enumCallStatus;
extern ReceiveStatus enumCRecvStatus;
extern ReceiveStatus enumSRecvStatus;
extern ClientFSM ClientState;
extern SendStatus enumCSendStatus;
// Internal functions
BOOL TimeOut( clock_t ctStart, double dbWaitTime);
/****************************************************************************
FUNCTION: AddName
PURPOSE: Adds a unique name (in lpLocalName) in name table and
returns a name number if successful.
****************************************************************************/
BYTE AddName ( LPSTR lpLocalName, BYTE * pbNameNum)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
/*
* Submit a Synchronous NCB.ADD.NAME
*/
pncbNCB->ncb_command = NCBADDNAME; /* Synchronous add name */
pncbNCB->ncb_lana_num = 0; /* assume single net */
_fmemcpy( (LPVOID) pncbNCB->ncb_name,
(LPVOID) lpLocalName,
NETBIOS_NAME_LENGTH
);
/*
* Check immediate return code and NCB_RETCODE as well
* as this is sync. call.
*/
iRc = NetBiosPostMessage(0, /* No Handle */
NO_MESSAGE, /* No Message */
NOTIFY_OFF, /* No Notify */
pncbNCB /* Ptr. to NCB */
);
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (bRc != NRC_GOODRET )
{
NcbFree((LPVOID) pncbNCB);
return (bRc);
}
// Return the Name Number
*pbNameNum = pncbNCB->ncb_num;
// Free the NCB
NcbFree((LPVOID) pncbNCB);
return (NRC_GOODRET);
}
/****************************************************************************
FUNCTION: DeleteName
PURPOSE: Deletes a local name (in lpLocalName) from
name table. Name number is specified in bNameNum.
****************************************************************************/
BYTE DeleteName( LPSTR lpLocalName, BYTE bNameNum)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
/*
* Submit a synchronous NCB.DEL.NAME
*/
pncbNCB->ncb_command = NCBDELNAME; /* Synchronous delete name */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_num = bNameNum ; /* Name Number */
_fmemcpy( (LPVOID) pncbNCB->ncb_name,
(LPVOID) lpLocalName,
NETBIOS_NAME_LENGTH
);
iRc = NetBiosPostMessage(0,
NO_MESSAGE,
NOTIFY_OFF,
pncbNCB
);
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
/*
* Check immediate return code and NCB_RETCODE as well
* as this is sync. call.
*/
if ( bRc != NRC_GOODRET )
{
NcbFree((LPVOID) pncbNCB);
return (bRc);
}
// Free the NCB
NcbFree((LPVOID) pncbNCB);
return NRC_GOODRET;
}
/****************************************************************************
FUNCTION: Call
PURPOSE: Tries to set up a connection(session) between local name
(in lpLocalName) and remote name (in lpRemoteName).
Upon successful completion, returns a local session
number in 'pbLsn'. Callers must set receive time out
and send time out values in 'bRto' and 'bSto'
respectively.
Effects/Requirements:
The function sets enumCallStatus to CALL_START after
submitting a NCB.CALL |ASYNCH.
After completion of the call command, the post
routine sends a call completion message to
window identified by 'hWnd'.
In browser sample program, the message goes to main window
(browser.c) where enumCallStatus gets set to either
CALL_CMPLT (no erro) or CALL_ERROR.
****************************************************************************/
BYTE Call ( HWND hWnd,
LPSTR lpLocalName,
LPSTR lpRemoteName,
BYTE bRto,
BYTE bSto,
BYTE *pbLsn
)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc;
MSG msg; /* Window Message */
clock_t ctStart;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
/*
* Make a asynchronous NCB.CALL
*/
pncbNCB->ncb_command = NCBCALL | ASYNCH; /* Asynchronous call */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_rto = bRto; /* Receice Time out */
pncbNCB->ncb_sto = bSto; /* Send Time out */
// Copy the local name. Assumes correct sized (NETBIOS_NAME_LENGTH) buffer
_fmemcpy( (LPVOID)pncbNCB->ncb_name,
(LPVOID)lpLocalName,
NETBIOS_NAME_LENGTH
);
// Copy the remote name. Assumes correct sized (NETBIOS_NAME_LENGTH) buffer
_fmemcpy( (LPVOID) pncbNCB->ncb_callname,
(LPVOID) lpRemoteName,
NETBIOS_NAME_LENGTH
);
iRc = NetBiosPostMessage(hWnd,
BW_CALL_BACK,
NOTIFY_IF_ASYNC,
pncbNCB
);
// Only if internal error happens, wnetbios returns -1. Else
// it will always post the message. However, sometimes a
// call can complete successfully right away
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (( bRc != NRC_PENDING) && (bRc != NRC_GOODRET))
{
NcbFree ((LPVOID) pncbNCB);
return (bRc);
}
/*
* Set up timer and a timeout for this call
*/
ctStart = clock();
/*
* Yield control and let other applications work
* while we wait for getting a connection
*/
enumCallStatus = CALL_START;
do
{
if (MessageLoop(&msg))
{
// WM_QUIT was received
PostQuitMessage(0);
Cancel ( pncbNCB);
NcbFree((LPVOID) pncbNCB);
return (NRC_CMDTMO); /* User got bored and timeed out! */
}
// Did we connect yet
if (enumCallStatus == CALL_CMPLT)
{
// Free the NCB
*pbLsn = pncbNCB->ncb_lsn;
NcbFree((LPVOID) pncbNCB);
return (NRC_GOODRET);
}
else if (enumCallStatus == CALL_ERROR)
{
bRc = pncbNCB->ncb_retcode;
// Free the NCB
*pbLsn = pncbNCB->ncb_lsn;
NcbFree((LPVOID) pncbNCB);
return (bRc);
}
}while ( TimeOut(ctStart, CALL_TIME_OUT)== FALSE);
// We time-ed out so cancel the Call command
Cancel ( pncbNCB);
// Free the NCB
NcbFree((LPVOID) pncbNCB);
return (NRC_CMDTMO);
}
/****************************************************************************
FUNCTION: Listen
PURPOSE: Post a asynchronous listen and returns without waiting
for completion of Listen. Users must set blank padded
16-byte long names in 'lpLocalName' and 'lpRemoteName'.
They must also set correct timeout values in
'bRto' (receive time out) and 'bSto' (send time out).
The function returns a pointer to the submitted NCB
which is allocated in fixed memory.
Effects/Requirements:
The function submits NCB.LISTEN | ASYNCH. The post
routine will thus send a completion message to
the window identified by 'hWnd'.
In browser sample program, the message is intercepted
by main window (browser.c) and processed.
****************************************************************************/
BYTE Listen ( HWND hWnd,
LPSTR lpLocalName,
LPSTR lpRemoteName,
BYTE bRto,
BYTE bSto,
PNCB *pncbListenPosted
)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc;
int iRc;
// Assume error will happen
*pncbListenPosted = NULL;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
/*
* Make a asynchronous NCB.LISTEN
*/
pncbNCB->ncb_command = NCBLISTEN | ASYNCH; /* Asynchronous Listen */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_rto = bRto; /* Receice Time out */
pncbNCB->ncb_sto = bSto; /* Send Time out */
// Copy the local name. Assumes blank padded NETBIOS_NAME_LENGTH sized
// buffer
_fmemcpy( (LPVOID) pncbNCB->ncb_name,
(LPVOID) lpLocalName,
NETBIOS_NAME_LENGTH
);
// Copy the remote name. Assumes blank padded NETBIOS_NAME_LENGTH sized
// buffer
_fmemcpy( (LPVOID)pncbNCB->ncb_callname,
(LPVOID)lpRemoteName,
NETBIOS_NAME_LENGTH
);
iRc = NetBiosPostMessage(hWnd,
BW_LISTEN_BACK,
NOTIFY_IF_ASYNC,
pncbNCB
);
// Only if internal error happens, wnetbios returns -1. Else
// it will always post the message.
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (( bRc != NRC_PENDING) && (bRc != NRC_GOODRET))
{
NcbFree ((LPVOID) pncbNCB);
return (bRc);
}
// No, errors. So , return Posted Listen NCB address
*pncbListenPosted = pncbNCB;
return ( bRc);
}
/****************************************************************************
FUNCTION: Send
PURPOSE: This function is used to send data asynchronously.
The caller specifies a buffer in 'lpData' and buffer
length in 'wDataLen'. The caller must also specify
the local session number in 'bLsn' which should be
valid. The caller specifies the message (in 'iMessage')
that post routine should send to the originating
window recognized by 'hWnd'. Finally, a variable
'peSendStatus' pointer must be provided.
The pointer 'peSendStatus' allows for "sender" to be either
a Client or a Sender.
Effect/Requirements: After submitting a NCB.SEND| ASYNCH,
the function sets 'peSendStatus' to SEND_START. It
is the caller's responsibility to set this
variable to either SEND_CMPLT or SEND_ERROR upon
receiving the post completion message ('iMessage').
In this sample, the work is done in browser.c.
****************************************************************************/
BYTE Send (HWND hWnd,
LPSTR lpData,
WORD wDataLen,
BYTE bLsn,
unsigned iMessage,
SendStatus *peSendStatus
)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc; /* Error return code */
MSG msg; /* Window Message */
LPSTR lpBuffer; /* NCB data buffer */
clock_t ctStart;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
// Allocate buffer the size of data buffer which will be
// locked in memory.
lpBuffer = (LPSTR) NcbAllocBuf( (DWORD) wDataLen );
if (lpBuffer==NULL)
{
NcbFree((LPVOID) pncbNCB);
return (ERROR_OUT_OF_MEMORY);
}
/*
* Make a asynchronous NCB.SEND
*/
pncbNCB->ncb_command = NCBSEND | ASYNCH; /* Asynchronous send */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_lsn = bLsn; /* Local Session Number */
pncbNCB->ncb_length = wDataLen; /* data length */
pncbNCB->ncb_buffer = lpBuffer; /* data in 'safe' memory */
// Copy the data into our buffer
_fmemcpy( (LPVOID) lpBuffer,
(LPVOID) lpData,
(size_t) wDataLen
);
iRc = NetBiosPostMessage(hWnd,
iMessage, // Notification Message
NOTIFY_IF_ASYNC,
pncbNCB
);
// Only if internal error happens, wnetbios returns -1. Else
// it will always post the message. However, sometimes
// a command can successfully complete right away
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (( bRc != NRC_PENDING) && (bRc != NRC_GOODRET))
{
NcbFree ((LPVOID) lpBuffer);
NcbFree ((LPVOID) pncbNCB );
return (bRc);
}
/*
* Set up timer and a timeout for this call
*/
ctStart = clock();
/*
* Yield control and let other applications work
* while we wait for getting a connection
*/
*peSendStatus = SEND_START;
do
{
if (MessageLoop(&msg))
{
// WM_QUIT was received
PostQuitMessage(0);
Cancel ( pncbNCB);
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) lpBuffer);
return (NRC_CMDTMO); /* User got bored and timeed out! */
}
// Did we complete send successfully yet?
if (*peSendStatus == SEND_CMPLT)
{
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) lpBuffer);
return (NRC_GOODRET);
}
else if (*peSendStatus == SEND_ERROR)
{
bRc = pncbNCB->ncb_retcode;
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) lpBuffer);
return (bRc);
}
}
while ( TimeOut(ctStart, SEND_TIME_OUT)== FALSE);
// We time-ed out so cancel the Send command
Cancel ( pncbNCB);
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) lpBuffer);
return (NRC_CMDTMO);
}
/****************************************************************************
FUNCTION: Receive
PURPOSE: Post a asynchronous receive. If 'fServer' is TRUE,
the routine returns immediately after submitting
the NCB. Otherwise (for Clients), it will loop
waiting for async. receive to complete. The caller
specifies the handle of window to receive completion
message in 'hWnd' and local session number in 'bLsn'.
The caler must specify the size of packet it
is expecting in 'wDataLen'. Accordingly, the routine
will allocate fixed memory which caller must release.
Effect/Requirements: For Clients, it posts a NCB.RECEIVE.ANY|ASYNCH
and loops after setting enumCRecvStatus = RECEIVE_START.
The Client (in this sample, browser.c) must
set it's value to RECEIVE_CMPLT or RECEIVE_ERROR after
receiving post routine message.
****************************************************************************/
BYTE Receive ( HWND hWnd,
LPSTR *ppLpData,
WORD wDataLen,
BYTE bLsn,
BOOL fServer
)
{
PNCB pncbNCB; /* Pointer to an NCB */
BYTE bRc; /* Error return code */
MSG msg; /* Window Message */
unsigned iMessage;/* Notification Message */
clock_t ctStart;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return (ERROR_OUT_OF_MEMORY);
// Allocate buffer the size of data buffer which will be
// locked in memory. The caller of Receive must free
// the buffer if pointer returned in non-NULL.
*ppLpData = (LPSTR) NcbAllocBuf( (DWORD) wDataLen );
if (*ppLpData==NULL)
{
NcbFree((LPVOID) pncbNCB);
return (ERROR_OUT_OF_MEMORY);
}
/*
* Make a asynchronous NCB.RECEIVE
*/
pncbNCB->ncb_command = NCBRECV | ASYNCH; /* Asynchronous Receive */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_lsn = bLsn; /* Local Session Number */
pncbNCB->ncb_length = wDataLen; /* data length */
pncbNCB->ncb_buffer = *ppLpData; /* data in 'safe' memory */
/*
* If server is calling, we simply submit the
* RECEIVE and return. If client is calling
* we loop just like in Send()
*/
if (fServer)
iMessage = BW_S_RECEIVE_BACK;
else
iMessage = BW_C_RECEIVE_BACK;
iRc = NetBiosPostMessage(hWnd,
iMessage, // Notification Message
NOTIFY_IF_ASYNC,
pncbNCB
);
// Only if internal error happens, wnetbios returns -1. Else
// it will always post the message. However, sometimes
// an NCB completes successfully right away.
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (( bRc != NRC_PENDING) && (bRc != NRC_GOODRET))
{
NcbFree ((LPVOID) pncbNCB );
return (bRc);
}
// In case of Server, we are done.
if (fServer)
{
return (NRC_PENDING);
}
/*
* Set up timer and a timeout for this call
*/
ctStart = clock();
/*
* Yield control and let other applications work
* while we wait for getting a connection
*/
enumCRecvStatus = RECEIVE_START;
do
{
if (MessageLoop(&msg))
{
// WM_QUIT was received
PostQuitMessage(0);
Cancel ( pncbNCB);
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) *ppLpData);
*ppLpData = NULL;
return (NRC_CMDTMO); /* User got bored and timeed out! */
}
// Did we complete send successfully yet?
if (enumCRecvStatus == RECEIVE_CMPLT)
{
// Free the NCB. The buffer must
// be freed by the caller.
NcbFree((LPVOID) pncbNCB);
return (NRC_GOODRET);
}
else if (enumCRecvStatus == RECEIVE_ERROR)
{
bRc = pncbNCB->ncb_retcode;
// Free the NCB . Buffer must be freed by
// Caller.
NcbFree((LPVOID) pncbNCB);
return (bRc);
}
}
while ( TimeOut(ctStart, RECEIVE_TIME_OUT)== FALSE);
// We time-ed out so cancel the Send command
Cancel ( pncbNCB);
// Free the NCB and the buffer
NcbFree((LPVOID) pncbNCB);
NcbFree((LPVOID) *ppLpData);
*ppLpData = NULL;
return (NRC_CMDTMO);
}
/****************************************************************************
FUNCTION: Hangup
PURPOSE: Posts a synchrnous NCB.HANGUP message given a local
session number in 'bLsn'.
****************************************************************************/
BYTE Hangup( BYTE bLsn)
{
BYTE bRc;
PNCB pncbNCB;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return ERROR_OUT_OF_MEMORY;
/*
* Submit a Synchronous NCB.HANGUP
*/
pncbNCB->ncb_command = NCBHANGUP; /* Synchronous hanup */
pncbNCB->ncb_lana_num = 0; /* assume single net */
pncbNCB->ncb_lsn = bLsn; /* Local Session Number */
iRc = NetBiosPostMessage(0, /* No Handle */
NO_MESSAGE, /* No Message */
NOTIFY_OFF, /* No Notify */
pncbNCB /* Ptr. to NCB */
);
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if ( bRc != NRC_GOODRET)
{
NcbFree((LPVOID) pncbNCB);
return bRc;
}
// Free the NCB
NcbFree((LPVOID) pncbNCB);
return NRC_GOODRET;
}
/****************************************************************************
FUNCTION: Cancel
PURPOSE: Posts a synchronous NCB.CANCEL command against the NCB
mentioned in 'pncbNCBToCancel'.
****************************************************************************/
BYTE Cancel( PNCB pncbNCBToCancel)
{
BYTE bRc;
PNCB pncbNCB;
int iRc;
// Allocate a NCB
pncbNCB = NcbAlloc( 1 );
if (pncbNCB==NULL)
return ERROR_OUT_OF_MEMORY;
/*
* Submit a Synchronous NCB.CANCEL
*/
pncbNCB->ncb_command = NCBCANCEL; /* Synchronous cancel */
pncbNCB->ncb_lana_num = 0; /* assume single net */
// Set in buffer the address of NCB to be cancelled
pncbNCB->ncb_buffer = (char far *) pncbNCBToCancel;
iRc = NetBiosPostMessage(0, /* No Handle */
NO_MESSAGE, /* No Message */
NOTIFY_OFF, /* No Notify */
pncbNCB /* Ptr. to NCB */
);
if (iRc == -1)
bRc = WNETBIOS_ERROR;
else
bRc = pncbNCB->ncb_retcode;
if (bRc != NRC_GOODRET)
{
NcbFree((LPVOID) pncbNCB);
return bRc;
}
// Free the NCB
NcbFree ((LPVOID) pncbNCB);
return (NRC_GOODRET);
}
/****************************************************************************
FUNCTION: R_getcwd()
PURPOSE: Remote getcwd() function. Gets remote current directory.
It operates like a Client for networking purposes.
****************************************************************************/
char * R_getcwd( HWND hWnd, BYTE bLsn, char * pszBuffer, int maxlen)
{
BYTE bRc;
LPSTR lpData;
PACKET FAR *pacPtr;
// Sanity Check
if ((pszBuffer==NULL)|| (maxlen > MAXPATH))
return NULL;
// Allocate a PACKET
lpData = (LPSTR) NcbAllocBuf ( (DWORD) PACKET_SIZE );
if (lpData==NULL)
return NULL;
pacPtr = (PACKET FAR *) lpData;
pacPtr->bCommand = R_GETCWD;
/*
* Set the Client in Send mode first
*/
ClientState = C_SENDING;
bRc = Send ( hWnd, // handle to send message to
lpData, // Data to Send
PACKET_SIZE, // Data buffer size
bLsn, // Local Session Number
BW_C_SEND_BACK, // Message sent upon completion
&enumCSendStatus // A signal.
);
NcbFree( (LPVOID) lpData); // Release the packet
if (bRc)
{
ClientState = C_CONNECTED;
return NULL;
}
/*
* Wait to Receive
*/
ClientState = C_RECEIVING;
bRc = Receive ( hWnd, // Handle to send message to
&lpData, // Pointer to Received buffer
maxlen, // Size of Receive buffer
bLsn, // Local Session Number
FALSE // It is a client
);
if (bRc)
{
ClientState = C_CONNECTED;
return NULL;
}
/*
* Copy returned data into local memory and free DLL allocated memory
*/
_fmemcpy ( pszBuffer, lpData, _fstrlen (lpData) );
NcbFree((LPVOID) lpData);
/*
* Restore Client State
*/
ClientState = C_CONNECTED;
return (pszBuffer);
}
/****************************************************************************
FUNCTION: R_dos_findfirst()
PURPOSE: Remote dos_findfirst. It behaves like a Client for networking
purposes.
****************************************************************************/
BYTE R_dos_findfirst( HWND hWnd,
BYTE bLsn,
char * pchFileName,
unsigned uAttrib,
FINDT *findFileInfo)
{
BYTE bRc;
LPSTR lpData;
PACKET FAR *pacPtr;
FINDFIRST FAR *pfindFirst;
// Sanity Check
if ((pchFileName==NULL)|| (findFileInfo == NULL))
return !(NRC_GOODRET) ;
// Allocate a packety to send to remote server
lpData = (LPSTR) NcbAllocBuf ( (DWORD) (PACKET_SIZE + sizeof (FINDFIRST)));
if (lpData==NULL)
return !( NRC_GOODRET) ;
pacPtr = (PACKET FAR *) lpData;
pacPtr->bCommand = R_FINDFIRST;
pfindFirst = (FINDFIRST FAR *) ( (LPSTR) pacPtr + sizeof (BYTE));
// Copy user values in the Find First packet
_fstrcpy(pfindFirst->chFileName, (LPSTR) pchFileName);
pfindFirst->uAttrib = uAttrib;
/*
* Set the Client in Send mode first
*/
ClientState = C_SENDING;
bRc = Send ( hWnd, // handle to send message to
lpData, // Data to Send
PACKET_SIZE + sizeof (FINDFIRST), // Data buffer size
bLsn, // Local Session Number
BW_C_SEND_BACK, // Message sent upon completion
&enumCSendStatus // A signal.
);
NcbFree( (LPVOID) lpData); // Release the packet
if (bRc)
{
ClientState = C_CONNECTED;
return !(NRC_GOODRET);
}
/*
* Wait to Receive
*/
ClientState = C_RECEIVING;
bRc = Receive ( hWnd, // Handle to send message to
&lpData, // Pointer to Received buffer
sizeof (FINDT), // Size of Receive buffer
bLsn, // Local Session Number
FALSE // It is a client
);
if (bRc)
{
ClientState = C_CONNECTED;
return !(NRC_GOODRET);
}
/*
* Returned data is merely a find_t structure. We copy it
* in local memory and free the locally allocated (fixed) memory
*/
_fmemcpy ( (LPVOID ) findFileInfo,
(LPVOID ) lpData,
sizeof (FINDT)
);
NcbFree((LPVOID) lpData);
/*
* Restore Client State
*/
ClientState = C_CONNECTED;
// We send -1 in find_t size if remote server encountered an error
if ( findFileInfo->size == -1)
return !(NRC_GOODRET);
else
return (NRC_GOODRET);
}
/****************************************************************************
FUNCTION: R_dos_findnext()
PURPOSE: Remote dos_findnext. It behaves like a Client for
networking purposes.
****************************************************************************/
BYTE R_dos_findnext( HWND hWnd,
BYTE bLsn,
FINDT *findFileInfo)
{
BYTE bRc;
LPSTR lpData;
PACKET FAR *pacPtr;
FINDNEXT FAR *pfindNext;
// Sanity Check
if ((findFileInfo == NULL))
return !(NRC_GOODRET) ;
// Allocate a packet to send to remote server
lpData = (LPSTR) NcbAllocBuf ( (DWORD) (PACKET_SIZE + sizeof (FINDNEXT)));
if (lpData==NULL)
return !(NRC_GOODRET) ;
pacPtr = (PACKET FAR *) lpData;
pacPtr->bCommand = R_FINDNEXT;
pfindNext = (FINDNEXT FAR *) ( (LPSTR) pacPtr + sizeof (BYTE));
// Copy remote find_t data back into the packet
_fmemcpy( (LPVOID) &(pfindNext->FileInfo),
(LPVOID) findFileInfo,
sizeof (FINDT)
);
/*
* Set the Client in Send mode first
*/
ClientState = C_SENDING;
bRc = Send ( hWnd, // handle to send message to
lpData, // Data to Send
PACKET_SIZE + sizeof (FINDNEXT), // Data buffer size
bLsn, // Local Session Number
BW_C_SEND_BACK, // Message sent upon completion
&enumCSendStatus // A signal.
);
NcbFree( (LPVOID) lpData); // Release the packet
if (bRc)
{
ClientState = C_CONNECTED;
return !(NRC_GOODRET);
}
/*
* Wait to Receive
*/
ClientState = C_RECEIVING;
bRc = Receive ( hWnd, // Handle to send message to
&lpData, // Pointer to Received buffer
sizeof (FINDT), // Size of Receive buffer
bLsn, // Local Session Number
FALSE // It is a client
);
if (bRc)
{
ClientState = C_CONNECTED;
return !(NRC_GOODRET);
}
/*
* Returned data is merely a find_t structure. We copy it
* in local memory and free the locally allocated (fixed) memory
*/
_fmemcpy ( (LPVOID ) findFileInfo,
(LPVOID ) lpData,
sizeof (FINDT)
);
NcbFree((LPVOID) lpData);
/*
* Restore Client State
*/
ClientState = C_CONNECTED;
// We send -1 in find_t size if remote server encountered an error
if ( findFileInfo->size == -1)
return !(NRC_GOODRET);
else
return (NRC_GOODRET);
}
/****************************************************************************
FUNCTION: TimeOut
PURPOSE: This function will return TRUE if duration of time
time elapsed from ctStart till "now" is >=
dbWaitTime, else FALSE.
****************************************************************************/
BOOL TimeOut( clock_t ctStart, double dbWaitTime)
{
clock_t ctCurrent; /* Current time in clock ticks */
ctCurrent = clock();
if (((double)(ctCurrent - ctStart)/ CLOCKS_PER_SEC ) >= dbWaitTime)
return TRUE;
else
return FALSE;
}